package com.scujj.controller.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.scujj.controller.UserController;
import com.scujj.pojo.Result;
import com.scujj.pojo.User;
import com.scujj.service.UserService;
import com.scujj.util.FileUtil;
import com.scujj.utils.JWTUtils;
import com.scujj.utils.PhoneNumberCheckCodeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/user")
@Api(tags = "用户信息管理")
@RefreshScope
public class UserControllerImpl implements UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private PhoneNumberCheckCodeUtil phoneNumberCheckCodeUtil;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Value("${staticFilePath}" + "${imgPath.headImg}")
    private String imgPath;
    @Value("${imgPath.headImg}")
    private String path;


    @Override
    @GetMapping("/login/checkCode/{phoneNumber}/{checkCode}")
    @ApiOperation(value = "手机号登录")
    public Result loginByPhoneNumber(@PathVariable("phoneNumber") String phoneNumber,
                                     @PathVariable("checkCode") String checkCode) {
        if (phoneNumber == null || checkCode == null) {
            return new Result(-1, "参数错误", null);
        }
        if (!phoneNumberCheckCodeUtil.checkCheckCode(phoneNumber, checkCode)) {
            return new Result(-1, "验证码错误", null);
        }
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phoneNumber", phoneNumber);
        User user = userService.getOne(wrapper);
        if (user == null) {
            return new Result(-1, "手机号尚未注册", null);
        }
        Map<String, Object> res = getTokenRes(user);
        return Result.success(res);
    }

    @Override
    @GetMapping("/login/{phoneNumber}/{password}")
    @ApiOperation("手机号密码登录")
    public Result loginByPhoneNumberAndPassword(@PathVariable("phoneNumber") String phoneNumber, @PathVariable("password") String password) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phoneNumber", phoneNumber).eq("password", password);
        User user = userService.getOne(wrapper);
        if (user == null) {
            return Result.error("用户名或密码错误");
        } else {
            getTokenRes(user);
            Map<String, Object> res = getTokenRes(user);
            return Result.success(res);
        }
    }


    @Override
    @PostMapping("/register")
    @ApiOperation(value = "手机号注册")
    public Result registerByPhoneNumber(@RequestBody HashMap<String, Object> args) {
        String phoneNumber = (String) args.get("phoneNumber");
        String checkCode = (String) args.get("checkCode");
        String gender = (String) args.get("gender");
        if (phoneNumber == null || checkCode == null || gender == null) {
            return new Result(-1, "参数错误", null);
        }
        if (!phoneNumberCheckCodeUtil.checkCheckCode(phoneNumber, checkCode)) {
            return new Result(-1, "验证码错误", null);
        }
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phoneNumber", phoneNumber);
        if (userService.getOne(wrapper) != null) {
            return new Result(-1, "该手机号已被注册", null);
        }
        User user = new User().setPhoneNumber(phoneNumber).setUserName(UUID.randomUUID().toString()).
                setGender(gender).setPassword("123456");
        if (userService.save(user)) {
            return new Result(0, "成功", user.setPassword(null));
        } else {
            return new Result(-1, "网络错误", null);
        }
    }

    @Override
    @GetMapping("/checkCode/{phoneNumber}")
    @ApiOperation(value = "手机号获取验证码")
    public Result getCheckCodeByPhoneNumber(@PathVariable("phoneNumber") String phoneNumber) {
        if (phoneNumberCheckCodeUtil.checkPhoneNumber(phoneNumber)) {
            return new Result(0, "成功", phoneNumberCheckCodeUtil.getCheckCode(phoneNumber));
        } else {
            return new Result(-1, "手机号格式错误", null);
        }
    }

    @Override
    @PostMapping("/updateUser")
    @ApiOperation(value = "修改用户信息")
    public Result updateUser(@RequestParam("id") Long id,
                             @RequestParam(value = "gender", required = false) String gender,
                             @RequestParam(value = "userName", required = false) String userName,
                             @RequestParam(value = "password", required = false) String password,
                             @ApiParam(value = "图片文件", required = false) @RequestParam(value = "headImg", required = false) MultipartFile img,
                             @RequestParam(value = "studentID", required = false) String studentID) {
        User user = userService.getById(id);
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        if (user == null) return new Result(-1, "用户不存在", null);
        wrapper.eq("id", user.getId());
        if (userName != null) {
            user.setUserName(userName);
            wrapper.set("userName", userName);
        }
        if (password != null) {
            user.setPassword(password);
            wrapper.set("password", password);
        }
        if (studentID != null) {
            user.setStudentID(studentID);
            wrapper.set("studentID", studentID);
        }
        if (gender != null) {
            user.setGender(gender);
            wrapper.set("gender", gender);
        }
        //上传图片代码
        if (img != null) {
            String fileName = FileUtil.uploadFile(imgPath, img);
            if (fileName == null) {
                return Result.error("图片上传失败");
            }
            user.setHeadImgSrc("api-static/" + path + fileName);
            wrapper.set("headImgSrc", user.getHeadImgSrc());
        }
        if (userService.update(wrapper)) {
            return new Result(0, "成功", user.setPassword(null));
        } else {
            return new Result(-1, "网络错误", null);
        }
    }

    @Override
    @GetMapping
    @ApiOperation("根据token获取当前登录的用户")
    public Result getUser(HttpServletRequest httpServletRequest) {
        String token = httpServletRequest.getHeader("token");
        if (token == null || token.equals("")) {
            return new Result(-1, "用户未登录", 0);
        }
        String idString = stringRedisTemplate.opsForValue().get(token);
        if (idString == null) {
            return new Result(-1, "用户未登录", 0);
        }
        Long id = Long.valueOf(idString);
        User user = userService.getById(id);
        if (user == null) {
            return new Result(-1, "用户不存在", null);
        } else {
            return new Result(0, "成功", user.setPassword(null));
        }
    }

    @Override
    @GetMapping("/id")
    @ApiOperation("根据id获取用户信息")
    public Result getUserByIdList(@RequestParam("id") List<Long> id) {
        List<User> users = userService.listByIds(id);
        users.forEach(user -> user.setPassword(null));
        return new Result(0, "成功", users);
    }

    @Override
    @PutMapping("/updatePhoneNumber")
    @ApiOperation("更新手机号")
    public Result updatePhoneNumber(@RequestBody HashMap<String, Object> args) {
        Long id = Long.valueOf((String) args.get("id"));
        System.out.println(id);
        String checkCode = (String) args.get("checkCode");
        String phoneNumber = (String) args.get("phoneNumber");
        if (checkCode == null || phoneNumber == null) {
            return new Result(-1, "参数错误", null);
        }
        User user = userService.getById(id);
        if (user == null) {
            return new Result(-1, "用户不存在", null);
        }
        if (phoneNumberCheckCodeUtil.checkCheckCode(phoneNumber, checkCode)) {
            user.setPhoneNumber(phoneNumber);
            if (userService.updateById(user)) {
                return new Result(0, "成功", user.setPassword(null));
            } else {
                return new Result(-1, "网络错误", null);
            }
        } else {
            return new Result(-1, "验证码错误", null);
        }
    }

    @Override
    @GetMapping("/userName/{userName}")
    @ApiOperation("根据用户名获取用户列表")
    public Result getUserByUserName(@PathVariable("userName") String userName) {
        if (userName == null || userName.equals("")) {
            return Result.error("参数错误");
        }
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("userName", userName);
        List<User> userList = userService.list(wrapper);
        userList.forEach(user -> user.setPassword(null));
        return Result.success(userList);
    }

    @Override
    @PutMapping("/addMoney")
    @ApiOperation("充值接口")
    public Result addMoney(@RequestBody HashMap<String, Long> map) {
        String message = changeMoney(map, true);
        if (message == null) {
            return Result.success();
        } else {
            return Result.error(message);
        }
    }

    @Override
    @PutMapping("/useMoney")
    @ApiOperation("消费接口")
    public Result useMoney(@RequestBody HashMap<String, Long> map) {
        String message = changeMoney(map, false);
        if (message == null) {
            return Result.success();
        } else {
            return Result.error(message);
        }
    }

    @Override
    @GetMapping("/logout")
    @ApiOperation("退出登录")
    public Result logout(HttpServletRequest httpServletRequest) {
        Result result = getUser(httpServletRequest);
        if (result.getCode() == -1) {
            return result;
        } else {
            String token = httpServletRequest.getHeader("token");
            Boolean delete = stringRedisTemplate.delete(token);
            if (Boolean.TRUE.equals(delete)) {
                return Result.success();
            } else {
                return Result.error("用户已退出登录");
            }
        }
    }

    private String changeMoney(HashMap<String, Long> map, boolean isadd) {
        Long id = map.get("id");
        Long money = map.get("money");
        if (id == null || money == null) {
            return "参数错误";
        }
        User user = userService.getById(id);
        if (user == null) {
            return "用户不存在";
        }
        if (isadd) {
            user.setMoney(user.getMoney() + money);
        } else {
            if (user.getMoney() < money) {
                return "余额不足";
            } else {
                user.setMoney(user.getMoney() - money);
            }
        }
        if (userService.updateById(user)) {
            return null;
        } else {
            return "网络错误";
        }
    }

    private Map<String, Object> getTokenRes(User user) {
        HashMap<String, String> map = new HashMap<>();
        UUID uuid = UUID.randomUUID();
        map.put("UUID", uuid.toString());
        map.put("userId", String.valueOf(user.getId()));
        String token = JWTUtils.getToken(map);
        stringRedisTemplate.opsForValue().set(token, String.valueOf(user.getId()));
        Map<String, Object> res = new HashMap<>();
        res.put("user", user.setPassword(null));
        res.put("token", token);
        return res;
    }
}